package com.showtao.front.service;

import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;

import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Colour;
import jxl.format.UnderlineStyle;
import jxl.write.Label;
import jxl.write.NumberFormat;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

import org.apache.cxf.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.showtao.common.enumeration.EErrorCode;
import com.showtao.common.exception.BizServiceException;
import com.showtao.common.security.repository.UserRepository;
import com.showtao.front.domain.MobileOrder;
import com.showtao.front.domain.Order;
import com.showtao.front.domain.OrderValidationCode;
import com.showtao.front.repository.MobileOrderRepository;
import com.showtao.front.repository.OrderRepository;
import com.showtao.front.repository.OrderValidationCodeRepository;

@Service
public class OrderService {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private OrderRepository orderRepository;
    @Autowired
    private OrderValidationCodeRepository orderValidationCodeRepository;
    @Autowired
    private SMSService smsService;
    @Autowired
    MobileOrderRepository mobileOrderRepository;
    private final static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
    
    @Transactional(readOnly = true)
    public Page<Order> findOrdersByMobile(String mobile, Pageable pageable){
        return orderRepository.findByReceiverPhone(mobile, pageable);
    }
    
    @Transactional(readOnly = true)
    public Page<MobileOrder> findMyOrdersPC(String mobile, Date startDate, Date endDate, Pageable pageable){
    	if(startDate==null){
    		Calendar c = Calendar.getInstance();
    		c.set(Calendar.YEAR, 1970);
    		c.set(Calendar.MONTH, 0);
    		c.set(Calendar.DAY_OF_MONTH, 1);
    		c.set(Calendar.HOUR_OF_DAY, 0);
    		c.set(Calendar.MINUTE, 0);
    		c.set(Calendar.SECOND, 0);
    		c.set(Calendar.MILLISECOND, 0);
    		startDate=c.getTime();
    	}
    	if(endDate==null){
    		endDate=new Date();
    	}
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    	return mobileOrderRepository.findMobileOrderPC(mobile, format.format(startDate), format.format(endDate), pageable);
    }
    
    @Transactional
    public void sendValidationCode(String mobile){
        if (StringUtils.isEmpty(mobile)) {
            throw new BizServiceException(EErrorCode.COMM_INTERNAL_ERROR,
                    "参数不正确");
        }
        OrderValidationCode ovc = orderValidationCodeRepository.getByMobile(mobile);
        if(ovc == null){
            ovc = new OrderValidationCode();
            ovc.setCreatedAt(Calendar.getInstance().getTime());
            ovc.setMobile(mobile);
        }
        DecimalFormat df = new DecimalFormat("0000");
        String code = df.format(Math.round(Math.random()*1000));
        smsService.sendMessage(mobile, "秀套网订单查询验证码：【"+code+"】，半小时内有效，打死都不告诉别人哦！");
        ovc.setCode(code);
        ovc.setUpdatedAt(Calendar.getInstance().getTime());
        orderValidationCodeRepository.save(ovc);
    }
    
    @Transactional
    public void validateCode(String mobile, String code){
        if (StringUtils.isEmpty(code)) {
            throw new BizServiceException(EErrorCode.COMM_INTERNAL_ERROR,
                    "参数不正确");
        }
        OrderValidationCode ovc = orderValidationCodeRepository.getByMobile(mobile);
        if(ovc==null){
            throw new BizServiceException(EErrorCode.COMM_INTERNAL_ERROR, "验证码"+code+"无效");
        }else if(StringUtils.isEmpty(ovc.getCode()) || ovc.getUpdatedAt() == null){
            throw new BizServiceException(EErrorCode.COMM_INTERNAL_ERROR, "验证码"+code+"已失效");
        }else if(!code.equals(ovc.getCode())){
            throw new BizServiceException(EErrorCode.COMM_INTERNAL_ERROR, "验证码"+code+"不正确");
        }else {
            Calendar c = Calendar.getInstance();
            c.setTime(ovc.getUpdatedAt());
            c.add(Calendar.MINUTE, 30);
            if(c.before(Calendar.getInstance())){
                throw new BizServiceException(EErrorCode.COMM_INTERNAL_ERROR, "验证码"+code+"已过期");
            }
        }
        ovc.setCode(null);
        ovc.setUpdatedAt(Calendar.getInstance().getTime());
        orderValidationCodeRepository.save(ovc);
    }
    
    public List<Order> findByReceiverPhoneAndOrderDate(String receiverPhone, Date startDate, Date endDate) throws Exception{
    	if(startDate==null){
    		Calendar c = Calendar.getInstance();
    		c.set(Calendar.YEAR, 1970);
    		c.set(Calendar.MONTH, 0);
    		c.set(Calendar.DAY_OF_MONTH, 1);
    		c.set(Calendar.HOUR_OF_DAY, 0);
    		c.set(Calendar.MINUTE, 0);
    		c.set(Calendar.SECOND, 0);
    		c.set(Calendar.MILLISECOND, 0);
    		startDate=c.getTime();
    	}
    	if(endDate==null){
    		endDate=new Date();
    	}
    	
    	return orderRepository.findByReceiverPhoneAndOrderDate(receiverPhone, startDate, endDate);
    }
    
    public List<MobileOrder> findMobileOrderByMobileAndCreatedDate(String mobile, Date startDate, Date endDate) throws Exception{
    	if(startDate==null){
    		Calendar c = Calendar.getInstance();
    		c.set(Calendar.YEAR, 1970);
    		c.set(Calendar.MONTH, 0);
    		c.set(Calendar.DAY_OF_MONTH, 1);
    		c.set(Calendar.HOUR_OF_DAY, 0);
    		c.set(Calendar.MINUTE, 0);
    		c.set(Calendar.SECOND, 0);
    		c.set(Calendar.MILLISECOND, 0);
    		startDate=c.getTime();
    	}
    	if(endDate==null){
    		endDate=new Date();
    	}
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    	return mobileOrderRepository.findMobileOrderByMobileAndCreatedDate(mobile, format.format(startDate), format.format(endDate));
    }
    
    public void exportMobileOrderByMobileAndCreatedDate(String mobile, Date startDate, Date endDate, OutputStream out) throws Exception{
    	List<MobileOrder> orders = findMobileOrderByMobileAndCreatedDate(mobile, startDate, endDate);
    	WritableWorkbook workBook = null;
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    	try{
    		workBook = Workbook.createWorkbook(out);
    		WritableSheet sheet = workBook.createSheet("我的订单", 0);
    		sheet.getSettings().setDefaultColumnWidth(18);
    		int row = 0; // 行数索引
			int column = 0; // 列索引
			String title[] = { "订单编号", "下单日期", "车主姓名", "车主手机", "车型编号", "产品名称", "颜色", "脚垫编号", "尾箱编号", "备注" };
			WritableFont titleFont = new WritableFont(
					WritableFont.createFont("宋体"), 10, WritableFont.BOLD,
					false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK);
			WritableFont contentFont = new WritableFont(
					WritableFont.createFont("宋体"), 10, WritableFont.NO_BOLD,
					false, UnderlineStyle.NO_UNDERLINE, Colour.BLACK);
			WritableCellFormat titleFormat = new WritableCellFormat(titleFont);
			titleFormat.setAlignment(Alignment.CENTRE);
			titleFormat.setBorder(Border.ALL, BorderLineStyle.THIN,
					Colour.BLACK);

			WritableCellFormat normalFormat = new WritableCellFormat(
					contentFont);
			normalFormat.setAlignment(Alignment.CENTRE);
			NumberFormat nf1 = new NumberFormat("0.0");
			WritableCellFormat numberFormat1 = new WritableCellFormat(nf1);
			numberFormat1.setFont(contentFont);
			numberFormat1.setAlignment(Alignment.LEFT);

			NumberFormat nf2 = new NumberFormat("0.00");
			WritableCellFormat numberFormat2 = new WritableCellFormat(nf2);
			numberFormat2.setFont(contentFont);
			numberFormat2.setAlignment(Alignment.LEFT);
			for (int i = 0; i < title.length; i++) {
				Label label = new Label(column++, row, title[i], titleFormat);
				sheet.addCell(label);
			}
			if(orders != null){
				for(MobileOrder mo:orders){
					row++;
					column = 0;
					Label orderNo = new Label(column++, row, mo.getOrderNo(), normalFormat);
					sheet.addCell(orderNo);
					
					Label createdDate = new Label(column++, row, sdf.format(mo.getCreatedAt()), normalFormat);
					sheet.addCell(createdDate);
					
					Label carOwner = new Label(column++, row, mo.getVehicleOwnerName(), normalFormat);
					sheet.addCell(carOwner);
					
					Label ownerMobile = new Label(column++, row, mo.getMobile(), normalFormat);
					sheet.addCell(ownerMobile);
					
					Label carTypeCode = new Label(column++, row, mo.getCarTypeCode(), normalFormat);
					sheet.addCell(carTypeCode);
					
					Label prodName = new Label(column++, row, mo.getProductName(), normalFormat);
					sheet.addCell(prodName);
					
					Label colour = new Label(column++, row, mo.getProductColour(), normalFormat);
					sheet.addCell(colour);
					
					Label footCode = new Label(column++, row, mo.getFootCode(), normalFormat);
					sheet.addCell(footCode);
					
					Label tailCode = new Label(column++, row, mo.getTailCode(), normalFormat);
					sheet.addCell(tailCode);
					
					Label descrn = new Label(column++, row, mo.getDescrn()==null?"":mo.getDescrn(), normalFormat);
					sheet.addCell(descrn);
				}
			}
			workBook.write();
    	}catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				workBook.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
    }
    
    @Transactional
    public void saveMobileOrder(MobileOrder order, String footAppend, String tailAppend){
    	if(order.getOrderNo()==null || order.getOrderNo().length()==0){ 
    		String dateStr = sdf.format(new Date());
    		String rdm = (1000 + new Random().nextInt(8999)) + "";
    		order.setOrderNo(dateStr+rdm);
    	}
    	if("checked".equals(footAppend)){
    		order.setFootCode(order.getCarTypeCode()+"-J1");
    	}
    	if("checked".equals(tailAppend)){
    		if(order.getHatchback()==null){
    			order.setTailCode(order.getCarTypeCode()+"-W1");
    		}
    		else if("two".equals(order.getHatchback())){
    			order.setTailCode(order.getCarTypeCode()+"-W1A");
    		}
    		else if("three".equals(order.getHatchback())){
    			order.setTailCode(order.getCarTypeCode()+"-W1B");
    		}
    	}
    	mobileOrderRepository.save(order);
    }
    
    public static void main(String[] args){
    	String no = sdf.format(new Date()) + (1000 + new Random().nextInt(8999)) + "";
    	System.out.println(no);
    }
}
